package com.zhss.microservice.server.node;

import com.zhss.microservice.server.network.ServerMessageReceiver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.zhss.microservice.server.persist.FilePersistUtils;

import java.util.concurrent.ConcurrentHashMap;

/**
 * 槽位数据管理组件
 */
public class SlotManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(SlotManager.class);

    /**
     * 槽位分配存储文件的名字
     */
    private static final String NODE_SLOTS_FILENAME = "node_slots";

    /**
     * master节点本地内存里的槽位
     */
    private ConcurrentHashMap<Integer, Slot> slots =
            new ConcurrentHashMap<>();
    /**
     * master节点的消息接收组件
     */
    private ServerMessageReceiver masterMessageReceiver;

    public SlotManager(ServerMessageReceiver masterMessageReceiver) {
        this.masterMessageReceiver = masterMessageReceiver;
    }

    /**
     * 初始化槽位数据
     */
    public void initSlots(String slotScope) {
        String[] slotScopeSplited = slotScope.split(",");
        Integer startSlotNo = Integer.valueOf(slotScopeSplited[0]);
        Integer endSlotNo = Integer.valueOf(slotScopeSplited[1]);

        for(Integer slotNo = startSlotNo; slotNo <= endSlotNo; slotNo++) {
            slots.put(slotNo, new Slot(slotNo));
        }
    }

    /**
     * 等待接收负责的槽位范围
     */
    public void waitForNodeSlots() {
        String slots = masterMessageReceiver.takeNodeSlots();
        // 先在内存里做一个初始化
        initSlots(slots);
        LOGGER.info("init slots in memory......");
        // 再把自己负责的槽位数据持久化到磁盘去
        byte[] bytes = slots.getBytes();
        FilePersistUtils.persist(bytes, NODE_SLOTS_FILENAME);
        LOGGER.info("persist node slots into local disk file......");
    }

    /**
     * 获取槽位对象
     * @param slotNumber
     * @return
     */
    public Slot getSlot(Integer slotNumber) {
        return slots.get(slotNumber);
    }

}
